/**
 * Project Name:fire-industry-DM-center
 * File Name:JWTAuthenticationFilter.java
 * Package Name:com.firestone.config.filter
 * Date:2018年3月22日上午10:16:03
 *
*/

package com.firestone.config.jwt;

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;

import com.firestone.bean.dto.user.User;
import com.firestone.core.constants.ConstantKey;

import io.jsonwebtoken.Jwts;

/**
 * @Description: TODO(token的校验
 *               该类继承自BasicAuthenticationFilter，在doFilterInternal方法中，
 *               从http头的token 项读取token数据，然后用Jwts包提供的方法校验token的合法性。
 *               如果校验通过，就认为这是一个取得授权的合法请求)
 * @author CAIYJ
 * @date 2018年3月22日 上午10:16:03
 */
public class JWTAuthenticationFilter extends BasicAuthenticationFilter {

    @Qualifier("userDetailsService")
    private UserDetailsService userDetailsService;

    public JWTAuthenticationFilter(AuthenticationManager authenticationManager,
            UserDetailsService userDetailsService) {
        super(authenticationManager);
        this.userDetailsService = userDetailsService;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request,
            HttpServletResponse response, FilterChain chain)
                    throws IOException, ServletException {
        String header = request.getHeader("token");
        String url = request.getRequestURI();
        if (header == null || !header.startsWith("Firestone ")) {
            chain.doFilter(request, response);
            return;
        }
        UsernamePasswordAuthenticationToken authentication = getAuthentication(
                request);
        SecurityContextHolder.getContext().setAuthentication(authentication);
        chain.doFilter(request, response);
    }

    private UsernamePasswordAuthenticationToken getAuthentication(
            HttpServletRequest request) {
        String token = request.getHeader("token");
        if (token != null) {
            // parse the token.
            String name = Jwts.parser().setSigningKey(ConstantKey.SIGNING_KEY)
                    .parseClaimsJws(token.replace("Firestone ", "")).getBody()
                    .getSubject();
            if (name != null) {
                User user = (User) userDetailsService.loadUserByUsername(name);
                return new UsernamePasswordAuthenticationToken(user,
                        user.getPassword(), user.getAuthorities());
            }
            return null;
        }
        return null;
    }

}
